import { fromArrayBuffer } from "geotiff";
// 创建，编译着色器程序
export const createShader = (gl: WebGLRenderingContext, type: number, source: string) => {
  // 创建着色器对象
  const shader = gl.createShader(type);
  if (!shader) {
    throw new Error("Failed to create shader");
  }
  // 将着色器源代码赋值给着色器对象
  gl.shaderSource(shader, source);

  // 编译着色器
  gl.compileShader(shader);
  // 检查着色器是否编译成功
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    // 如果编译失败，抛出错误
    throw new Error("Failed to compile shader: ");
  }
  // 返回着色器对象
  return shader;
};

// 创建着色器程序
export const createProgram = (gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) => {
  // 创建一个程序
  const program = gl.createProgram();
  if (program == null) {
    throw new Error("Failed to create program");
  }
  // 将顶点着色器和片元着色器附加到程序上
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);

  // 链接程序
  gl.linkProgram(program);
  // 如果链接失败，抛出错误
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    throw new Error("Failed to link program: ");
  }
  const wrapper = {
    program,
    a_position: gl.getAttribLocation(program, "a_position"),
    a_texCoord: gl.getAttribLocation(program, "a_texCoord"),
    u_matrix: gl.getUniformLocation(program, "u_matrix"),
    u_image0: gl.getUniformLocation(program, "u_image0"),
    u_image1: gl.getUniformLocation(program, "u_image1"),
    thresholdsStart: gl.getUniformLocation(program, "thresholdsStart"),
    thresholdsEnd: gl.getUniformLocation(program, "thresholdsEnd"),
    thresholds: gl.getUniformLocation(program, "thresholds"),
    colors: gl.getUniformLocation(program, "colors"),
    factor: gl.getUniformLocation(program, "factor"),
    hasTwoTextures: gl.getUniformLocation(program, "hasTwoTextures")
  };

  return wrapper;
};

// 导出一个函数，用于创建纹理
// 创建一个纹理对象
export const createTexture = (gl: WebGLRenderingContext, canvas: any, type: number) => {
  // 激活纹理单元
  if (type === 0) {
    gl.activeTexture(gl.TEXTURE0);
  } else {
    gl.activeTexture(gl.TEXTURE1);
  }
  // 创建一个纹理对象
  const texture = gl.createTexture();
  // 绑定纹理对象
  gl.bindTexture(gl.TEXTURE_2D, texture);
  // 上载数据
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
  // 设置纹理的环绕方式为边缘环绕
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  return texture;
};

// 根据tiff， 获取canvas
export const getCanvasByTiff = async (url: string) => {
  // 解析tiff
  const response = await fetch(url);
  const buffer = await response.arrayBuffer();
  const tiff = await fromArrayBuffer(buffer);
  const image = await tiff.getImage();
  const imageWidth = image.getWidth();
  const imageHeight = image.getHeight();
  const [red = [], green = [], blue = []] = await image.readRasters();
  // 创建canvas对象供纹理采样
  const canvas = document.createElement("canvas");
  canvas.width = imageWidth;
  canvas.height = imageHeight;
  const ctx = canvas.getContext("2d");
  if (!ctx) {
    return null;
  }
  let imageData = ctx.createImageData(imageWidth, imageHeight);
  for (let i = 0; i < imageData.data.length / 4; i += 1) {
    imageData.data[i * 4 + 0] = red[i];
    imageData.data[i * 4 + 1] = green[i] || 0;
    imageData.data[i * 4 + 2] = blue[i] || 0;
    imageData.data[i * 4 + 3] = red[i] === 0 ? 0 : 255;
  }
  ctx.putImageData(imageData, 0, 0);
  return canvas;
};
